﻿using System;
using System.Web.UI.WebControls;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;

namespace OrbitOne.SharePoint.MasterPagePicker
{
    public partial class MasterPagePicker : LayoutsPageBase
    {
        protected override void OnLoad(EventArgs e)
        {
            if (!this.IsPostBack)
            {
                InitRadioListSelected();
                BindControls(rdlistGallery.SelectedValue);
            }
            base.OnLoad(e);
        }

        /// <summary>
        /// Bind the controls with Master Page data gallery based on current or top site
        /// </summary>
        /// <param name="type">local for current, top for rootweb</param>
        private void BindControls(string type)
        {
            // create a list selector
            SPWeb webMasterPage = GetWebSelected(type);
                SPList list = webMasterPage.GetListFromUrl("_catalogs/masterpage/Forms/AllItems.aspx");

                // populate it with the values from the central master page list.
                //SPDataSource dataSource = new SPDataSource();
                this.MasterPageList.Items.Clear();
                SPField fiFile = GetFileField(list);

                foreach (SPListItem item in list.Items)
                {
                    string itName = item[fiFile.Id].ToString();
                    if (itName.IndexOf(".master") != -1)
                    {
                        this.MasterPageList.Items.Add(new ListItem(itName, itName));
                    }
                }

                String pageValue = SPContext.Current.Web.MasterUrl;
                String TokenMaster = "/_catalogs/masterpage/";

                // fill the master url literal
                LitMST.Text = pageValue;

                int position = pageValue.ToLowerInvariant().IndexOf(TokenMaster);
                if (position != -1)
                {
                    pageValue = pageValue.Substring(position + TokenMaster.Length, pageValue.Length - (position + TokenMaster.Length));
                }

                try
                {
                    this.MasterPageList.SelectedValue = pageValue;
                }

                catch (Exception) { this.MasterPageList.SelectedIndex = 0; }
            
        }

        /// <summary>
        /// Calcul the relative Master page URL and apply it to the current web site
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void DoSubmit(object sender, EventArgs e)
        {
            SPWeb webMasterPage = GetWebSelected(rdlistGallery.SelectedValue); ;
            SPWeb webRef = SPContext.GetContext(this.Context).Web;

            string webPathMasterUrl = GetFullPath(webMasterPage);
            string webPathUrl = GetFullPath(webRef);

            webRef.MasterUrl = webPathMasterUrl + "_catalogs/masterpage/" + this.MasterPageList.SelectedValue;
            webRef.Update();
            Response.Redirect(webPathUrl + "default.aspx");
        }

        /// <summary>
        /// Calculate the relative Master page URL and apply it to the current web site and all its sub site
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void DoSubmitAll(object sender, EventArgs e)
        {
            SPWeb webMasterPage = GetWebSelected(rdlistGallery.SelectedValue);
            SPWeb webRef = SPContext.GetContext(this.Context).Web;

            string webPathMasterUrl = GetFullPath(webMasterPage);
            string webPathUrl = GetFullPath(webRef);

            string URLmaster = webPathMasterUrl + "_catalogs/masterpage/" + this.MasterPageList.SelectedValue;

            updateMasterWeb(webRef, URLmaster);
            Response.Redirect(webPathUrl + "default.aspx");

        }

        /// <summary>
        /// Calculate the relative Master page URL and apply it to the current web site and all its sub site
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void DoResetAll(object sender, EventArgs e)
        {
            SPWeb webRef = SPContext.GetContext(this.Context).Web;
            string webPathUrl = GetFullPath(webRef);

            string DefaultMaster = "default.master";

            ResetMasterWeb(webRef, DefaultMaster);

            Response.Redirect(webPathUrl + "default.aspx");

        }

        /// <summary>
        /// Event of the radio button list : rebind the listbox
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void rdlistGallery_SelectedIndexChanged(object sender, EventArgs e)
        {
            BindControls(rdlistGallery.SelectedValue);
        }



        /// <summary>
        /// Init the radio button list.The pre selection check the current url to detect root or local site Master reference
        /// </summary>
        private void InitRadioListSelected()
        {
            try
            {
                SPWeb webRef = SPContext.GetContext(this.Context).Web;

                if (webRef.IsRootWeb)
                {
                    this.rdlistGallery.Items.Remove(this.rdlistGallery.Items.FindByValue("local"));
                    this.rdlistGallery.SelectedIndex = 0;
                }
                else
                {

                    string StartUrl = GetFullPath(webRef) + "_catalogs/masterpage/";
                    if (webRef.MasterUrl.StartsWith(StartUrl, StringComparison.InvariantCultureIgnoreCase))
                        this.rdlistGallery.SelectedValue = "local";
                    else
                        this.rdlistGallery.SelectedValue = "top";
                }
            }
            catch (Exception) { this.rdlistGallery.SelectedIndex = 0; }

        }


        /// <summary>
        /// Recurssive procedure : apply this master page to all sub sites
        /// </summary>
        /// <param name="web">Web target</param>
        /// <param name="masterUrl">Master page url</param>
        private void updateMasterWeb(SPWeb web, string masterUrl)
        {
            web.MasterUrl = masterUrl;
            web.Update();

            foreach (SPWeb subweb in web.GetSubwebsForCurrentUser())
            {
                updateMasterWeb(subweb, masterUrl);
            }
            web.Dispose();


        }

        /// <summary>
        /// Recurssive procedure : reset this master page to all sub sites
        /// </summary>
        /// <param name="web">Web target</param>
        /// <param name="masterPageName">Master page name</param>
        private void ResetMasterWeb(SPWeb web, string masterPageName)
        {
            string webPathUrl = GetFullPath(web);

            string URLmaster = webPathUrl + "_catalogs/masterpage/" + masterPageName;
            web.MasterUrl = URLmaster;
            web.Update();

            foreach (SPWeb subweb in web.GetSubwebsForCurrentUser())
            {
                ResetMasterWeb(subweb, masterPageName);
            }
            web.Dispose();
        }

        /// <summary>
        /// Get the SPfield for the master gallery
        /// </summary>
        /// <param name="plist"></param>
        /// <returns></returns>
        private SPField GetFileField(SPList plist)
        {
            SPFieldCollection FiColl = plist.Fields;
            return FiColl.GetFieldByInternalName("FileLeafRef");
        }


        /// <summary>
        /// Get the web selected upon its type
        /// </summary>
        /// <param name="type">local for current, top for rootweb</param>
        /// <returns>the SPweb </returns>
        private SPWeb GetWebSelected(string type)
        {
            SPWeb web;
            if (type == "local")
                web = SPContext.GetContext(this.Context).Web;
            else
                web = SPContext.GetContext(this.Context).Site.RootWeb;
            return web;
        }

        /// <summary>
        /// get the ful relative URL from the SPweb
        /// </summary>
        /// <param name="webRef"></param>
        /// <returns></returns>
        private string GetFullPath(SPWeb webRef)
        {
            string webPathUrl = webRef.ServerRelativeUrl;
            if (webPathUrl[webPathUrl.Length - 1] != '/')
                webPathUrl += "/";

            return webPathUrl;
        }

    }
}
